package me.qi.kancha.applet.vwork;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import me.qi.kancha.applet.AppletLoginSdk;
import me.qi.kancha.applet.DataStore;
import me.qi.kancha.dto.core.WxAppDTO;
import me.qi.kancha.service.WxAppService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class VWorkApi {

    private static final Logger log = LoggerFactory.getLogger(AppletLoginSdk.class);

    private final DataStore dataStore;

    private final RestTemplateBuilder restTemplateBuilder;

    private final WxAppService wxAppService;

    public VWorkApi(DataStore dataStore,
                          RestTemplateBuilder restTemplateBuilder,
                    WxAppService wxAppService) {
        this.dataStore = dataStore;
        this.restTemplateBuilder = restTemplateBuilder;
        this.wxAppService = wxAppService;
    }

    /**
     * 企业微信获取用户信息
     *
     * @param appId
     * @param code
     * @return
     */
    public String getUserInfo(String appId, String code) {
        String token = getVWorkToken(appId);
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={1}&code={2}";
        RestTemplate restTemplate = restTemplateBuilder.build();
        // restTemplate.setRequestFactory(proxy());

        String str = restTemplate
                .getForObject(url, String.class, token, code);
        Map result = new Gson().fromJson(str, Map.class);
        if (!isSuccess(result)) {
            String message = String.format("企业微信 %s 获取用户信息失败:%s", appId, result.toString());
            log.error(message);
            throw new RuntimeException(message);
        }
        return (String) result.get("UserId");
    }


    /**
     * 从数据库&redis获取 appSecret
     * @param appId
     * @return
     */
    public String getAppSecret(String appId) {
        String secret = dataStore.readSecret(appId);
        if (secret == null) {
            LambdaQueryWrapper<WxAppDTO> wrapper = new LambdaQueryWrapper();
            wrapper.eq(WxAppDTO::getAppId, appId);
            WxAppDTO wxAppDTO = wxAppService.getOne(wrapper);
            if (wxAppDTO == null) {
                throw new RuntimeException("未注册appid");
            }
            secret = wxAppDTO.getAppSecret();
            dataStore.storeSecret(appId, secret);
        }
        return secret;
    }

    /**
     * 从数据库&redis获取 企业微信AccessToken
     * @param appId corpid:agentid
     * @return
     */
    public String getVWorkToken(String appId) {
        String token = dataStore.readVWorkToken(appId);
        if(token == null) {
            String secret = getAppSecret(appId);
            String corpid = appId.split(":")[0];
            String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={1}&corpsecret={2}";
            RestTemplate restTemplate = restTemplateBuilder.build();
            // restTemplate.setRequestFactory(proxy());
            String str = restTemplate
                    .getForObject(url, String.class, corpid, secret);
            Map result = new Gson().fromJson(str, Map.class);
            if (!isSuccess(result)) {
                String message = String.format("企业微信 %s 获取AccessToken失败:%s", appId, result.toString());
                log.error(message);
                throw new RuntimeException(message);
            }
            token = (String) result.get("access_token");
            dataStore.storeVWorkToken(appId, token);
        }
        return token;
    }

    /**
     * 从数据库&redis获取 企业微信AccessToken
     * @param appId corpid:agentid
     * @param parentId
     * @return
     */
    public List getDeptList(String appId, Integer parentId) {
        String vWorkToken = getVWorkToken(appId);
        String url = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token={1}&id={2}";
        RestTemplate restTemplate = restTemplateBuilder.build();
        // restTemplate.setRequestFactory(proxy());
        String str = restTemplate
                .getForObject(url, String.class, vWorkToken, parentId);
        Map result = new Gson().fromJson(str, Map.class);
        if (!isSuccess(result)) {
            String message = String.format("企业微信%s获取部门列表失败:%s", appId, result.toString());
            log.error(message);
            throw new RuntimeException(message);
        }
        return (ArrayList) result.get("department");
    }

    /**
     * 获取部门用户
     * @param id
     * @return
     */
    public List<Map> getUserListByDeptId(String appId, Integer id) {
        String vWorkToken = getVWorkToken(appId);
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token={1}&department_id={2}";
        RestTemplate restTemplate = restTemplateBuilder.build();
        // restTemplate.setRequestFactory(proxy());
        String str = restTemplate
                .getForObject(url, String.class, vWorkToken, id);
        Map result = new Gson().fromJson(str, Map.class);
        if (!isSuccess(result)) {
            String message = String.format("企业微信%s获取部门列表失败:%s", appId, result.toString());
            log.error(message);
            throw new RuntimeException(message);
        }
        return (ArrayList) result.get("userlist");
    }

    /**
     * 读取用户
     *
     * @param appId
     * @param userid
     * @return
     */
    public Map getUserByUserid(String appId, String userid) {
        String vWorkToken = getVWorkToken(appId);
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={1}&userid={2}";
        RestTemplate restTemplate = restTemplateBuilder.build();
        // restTemplate.setRequestFactory(proxy());
        String str = restTemplate
                .getForObject(url, String.class, vWorkToken, userid);
        Map result = new Gson().fromJson(str, Map.class);
        if (!isSuccess(result)) {
            String message = String.format("企业微信%s读取用户失败:%s", appId, result.toString());
            log.error(message);
            throw new RuntimeException(message);
        }
        return result;
    }

    /**
     * 发送文本卡片消息
     *
     * @param appId
     * @return
     */
    public Map sendTextCard(String appId, List<String> ids, String title, String content, String toUrl) {
        String vWorkToken = getVWorkToken(appId);
        String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={1}";
        Map data = new HashMap();
        data.put("touser", String.join("|", ids));
        data.put("msgtype", "textcard");
        data.put("agentid", appId.split(":")[1]);
        Map<String, String> card = new HashMap<>();
        card.put("title", title);
        card.put("description", description(content));
        card.put("url", toUrl);
        data.put("textcard", card);
        data.put("enable_id_trans", 1);
        RestTemplate restTemplate = restTemplateBuilder.build();
        // restTemplate.setRequestFactory(proxy());
        String str = restTemplate
                .postForObject(url, data, String.class, vWorkToken);
        Map response = new Gson().fromJson(str, Map.class);
        if (!isSuccess(response)) {
            String message = String.format("企业微信%s读取用户失败:%s", appId, response.toString());
            log.error(message);
            throw new RuntimeException(message);
        }
        Map result = new HashMap();
        result.put("request", data);
        result.put("response", response);
        return result;
    }

    private String description(String content) {
        String time = LocalDateTime.now()
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:ss"));
        String pattern = "<div class=\"gray\">时间：%s</div> <div class=\"normal\">%s</div>";
        return String.format(pattern, time, content);
    }

    // private SimpleClientHttpRequestFactory proxy() {
    //     SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    //     requestFactory.setProxy(new Proxy(Proxy.Type.HTTP,
    //             new InetSocketAddress("121.4.193.136", 3128)));
    //     return requestFactory;
    // }

    /**
     * errcode == 0
     *
     * @return
     */
    private boolean isSuccess(Map<String, Object> result) {
        Object errcode = result.get("errcode");

        return errcode == null || errcode.equals(0) || ((Double) errcode).intValue() == 0;
    }


}
